#include <cstdio>

const int N = 100005;
int n, m, a[N];

struct Node {
  int fa, ch[2], val;
  bool rev;
} tr[N];

inline bool iden(int x) { return tr[tr[x].fa].ch[1] == x; }

inline void pushup(int x) {
  tr[x].val = tr[tr[x].ch[0]].val ^ tr[tr[x].ch[1]].val ^ a[x];
}

inline void reverse(int x) {
  int tmp = tr[x].ch[0];
  tr[x].ch[0] = tr[x].ch[1];
  tr[x].ch[1] = tmp;
  tr[x].rev ^= 1;
}

inline void pushdown(int x) {
  if (tr[x].rev) {
    if (tr[x].ch[0]) reverse(tr[x].ch[0]);
    if (tr[x].ch[1]) reverse(tr[x].ch[1]);
    tr[x].rev = false;
  }
}

inline bool isrt(int x) { return tr[tr[x].fa].ch[0] != x && tr[tr[x].fa].ch[1] != x; }

void pd(int x) {
  if (!isrt(x)) pd(tr[x].fa);
  pushdown(x);
}

inline void rotate(int x) {
  int fa = tr[x].fa, ffa = tr[fa].fa, k = tr[fa].ch[1] == x, w = tr[x].ch[!k];
  if (!isrt(fa)) tr[ffa].ch[tr[ffa].ch[1] == fa] = x;
  tr[x].ch[!k] = fa;
  tr[fa].ch[k] = w;
  if (w) tr[w].fa = fa;
  tr[fa].fa = x;
  tr[x].fa = ffa;
  pushup(fa);
}

inline void splay(int x) {
  pd(x);
  while (!isrt(x)) {
    if (!isrt(tr[x].fa)) rotate(iden(tr[x].fa) == iden(x) ? tr[x].fa : x);
    rotate(x);
  }
  pushup(x);
}

inline void access(int x) {
  for (int y = 0; x; y = x, x = tr[x].fa) splay(x), tr[x].ch[1] = y, pushup(x);
}

inline int findrt(int x) {
  access(x);
  splay(x);
  while (tr[x].ch[0]) { pushdown(x), x = tr[x].ch[0]; }
  splay(x);
  return x;
}

inline void makert(int x) { access(x), splay(x), reverse(x); }

inline void split(int x, int y) {
  makert(x);
  access(y), splay(y);
}

inline void cut(int x, int y) {
  makert(x);
  if (findrt(y) == x && tr[y].fa == x && !tr[y].ch[0])
    tr[x].ch[1] = tr[y].fa = 0, pushup(x);
}

inline void link(int x, int y) {
  makert(x);
  if (findrt(y) != x) tr[x].fa = y;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen64("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen64("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("LCT.in", "r", stdin);
  freopen("LCT.out", "w", stdout);
#endif
#endif

  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
  for (int x, y, opt; m; --m) {
    scanf("%d%d%d", &opt, &x, &y);
    switch (opt) {
      case 0:
        split(x, y), printf("%d\n", tr[y].val);
        break;
      case 1:
        link(x, y);
        break;
      case 2:
        cut(x, y);
        break;
      default:
        splay(x), a[x] = y;
    }
  }
  return 0;
}